package com.gxk.actor;

import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.gxk.res.AnimationFactory;
import com.gxk.res.PublicConst;
import com.gxk.sound.VoiceHandle;
import com.gxk.util.Point;

public class BirdActor extends Actor {

	private float x;
	private float y;
	private float acceleration;
	private float statetime;

	private float currentSpeed;

	private Point[] points;

	private Rectangle birdRectangle;

	private TextureRegion currentFrame;

	private TextureRegion dieFrameRegion;

	private Animation birdaAnimation;

	private float rotationAngle;

	public STATE state;

	public enum STATE {
		Ready, Fly, Die
	};

	public BirdActor(float x, float y) {
		this.x = x;
		this.y = y;

		this.create();
		this.birdInit();
	}

	private void create() {
		this.acceleration = PublicConst.BRID_ACCELERATION;
		this.birdaAnimation = AnimationFactory.getBirdAnimation();
		this.dieFrameRegion = birdaAnimation.getKeyFrames()[1];
		this.points = new Point[4];
	}

	private void birdInit() {
		points[0] = new Point(x, y);
		points[1] = new Point(x + 34, y);
		points[2] = new Point(x, y + 24);
		points[3] = new Point(x + 34, y + 24);

		state = STATE.Ready;
	}

	@Override
	public void act(float delta) {
		statetime += delta;
		this.update(delta);
		this.check();
		super.act(delta);
	}

	@Override
	public void draw(Batch batch, float parentAlpha) {
		this.drawBird(batch, currentSpeed);
		super.draw(batch, parentAlpha);
	}

	private void drawBird(Batch batch, float currentSpeed) {
		batch.draw(currentFrame, this.x, this.y, 0, 0, 34, 24, 1, 1,
				rotationAngle);
	}

	private void update(float delta) {
		this.birdUpdate(delta);
		this.rotationUpdate(delta);
		this.pointsUpdate();
	}

	private void birdUpdate(float delta) {
		if (state == STATE.Fly) {
			this.y -= 1000 * (currentSpeed * delta + 1.0 / 2 * acceleration
					* delta * delta);
			this.currentSpeed += acceleration * delta;

		} else if (state == STATE.Die && this.y > 146) {
			this.y -= 1000 * (currentSpeed * delta + 1.0 / 2 * acceleration
					* delta * delta);
			this.currentSpeed += acceleration * delta;
		}
	}

	private void rotationUpdate(float delta) {
		if (currentSpeed < Math.abs(PublicConst.BRID_SPEED_ONTOUCH)) {
			if (rotationAngle < PublicConst.BRID_MAX_UP_ANDLE) {
				rotationAngle += delta * 250;
			} else {
				rotationAngle = PublicConst.BRID_MAX_UP_ANDLE;
			}
		} else {

			rotationAngle -= delta * 250;

			if (rotationAngle < -90) {
				rotationAngle = -90;
			}
		}

		if (state == STATE.Ready) {
			rotationAngle = 0;
		}
	}

	private void pointsUpdate() {

		points[0].x = this.x;
		points[0].y = this.y;

		float cos = (float) Math.cos(Math.abs(rotationAngle) / 180 * Math.PI);
		float sin = (float) Math.sin(Math.abs(rotationAngle) / 180 * Math.PI);

		if (rotationAngle == PublicConst.BRID_MAX_UP_ANDLE) {

			points[1].x = points[0].x + 34 * cos;
			points[1].y = points[0].y + 34 * sin;

			points[2].x = points[0].x - 24 * sin;
			points[2].y = points[0].y + 24 * cos;

			points[3].x = points[2].x + 34 * cos;
			points[3].y = points[2].y + 34 * sin;

		} else if (rotationAngle == -90) {

			points[1].x = points[0].x;
			points[1].y = points[0].y - 34;

			points[2].x = points[0].x + 24;
			points[2].y = points[0].y;

			points[3].x = points[2].x + 24;
			points[3].y = points[2].y - 34;
		} else if (rotationAngle == 0) {

			points[1].x = points[0].x + 34;
			points[1].y = points[0].y;

			points[2].x = points[0].x;
			points[2].y = points[0].y + 24;

			points[3].x = points[2].x + 24;
			points[3].y = points[2].y + 34;
		} else {
			points[1].x = points[0].x + 34 * cos;
			points[1].y = points[0].y - 34 * sin;

			points[2].x = points[0].x + 24 * sin;
			points[2].y = points[0].y + 24 * cos;

			points[3].x = points[2].x + 34 * cos;
			points[3].y = points[2].y - 34 * sin;
		}

	}

	public void touchDown() {
		if (this.y >= PublicConst.WORLD_HEIGHT) {
			return;
		}

		this.currentSpeed = PublicConst.BRID_SPEED_ONTOUCH;

		if (state == STATE.Ready) {
			state = STATE.Fly;
			VoiceHandle.play("fly");
		} else if (state == STATE.Fly) {
			VoiceHandle.play("fly");
		} else {

		}
	}

	public Point[] getPoints() {
		return points;
	}

	private void check() {
		if (state == STATE.Die) {
			currentFrame = dieFrameRegion;
		} else {
			currentFrame = birdaAnimation.getKeyFrame(statetime, true);
		}
	}

	public Rectangle getBirdRectangle() {
		return birdRectangle;
	}

	public void die(int i) {
		state = STATE.Die;

		VoiceHandle.play("die");

		if (i == 1) {
			VoiceHandle.play("hit");
		}
	}

	public float getX() {
		return this.x;
	}

	public float getY() {
		return this.y;
	}

	@Override
	public void setPosition(float x, float y) {
		this.x = x;
		this.y = y;
	}
}
